package com.fausto.learnimprint.config

import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonDeserializer
import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.authority.SimpleGrantedAuthority
import java.io.IOException
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.format.DateTimeFormatter
import java.util.*


/**
 *      配置JSON转换
 */
@Configuration
class JacksonConfig {

    /**
     *      添加日期格式转换
     */
    @Bean
    fun objectMapper(): ObjectMapper {
        val objectMapper = ObjectMapper()

        // 时间模块序列化处理
        val javaTimeModule = JavaTimeModule()

        javaTimeModule.addSerializer(
            LocalDateTime::class.java,
            LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
        )
        javaTimeModule.addSerializer(
            LocalDate::class.java,
            LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
        )
        javaTimeModule.addSerializer(
            LocalTime::class.java,
            LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss"))
        )
        javaTimeModule.addDeserializer(
            LocalDateTime::class.java,
            LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
        )
        javaTimeModule.addDeserializer(
            LocalDate::class.java,
            LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
        )
        javaTimeModule.addDeserializer(
            LocalTime::class.java,
            LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss"))
        )

        objectMapper.registerModule(javaTimeModule)
        return objectMapper
    }

}

/**
 *          自定义UserDetails的反序列化器
 */
class CustomAuthorityDeserializer : JsonDeserializer<Any>() {
    @Throws(IOException::class)
    override fun deserialize(jp: JsonParser, ctxt: DeserializationContext): Any {
        val mapper = jp.codec as ObjectMapper
        val jsonNode: JsonNode = mapper.readTree(jp)
        val grantedAuthorities: MutableList<GrantedAuthority> = LinkedList()
        val elements: Iterator<JsonNode> = jsonNode.elements()
        while (elements.hasNext()) {
            val next: JsonNode = elements.next()
            val authority: JsonNode = next.get("authority")
            grantedAuthorities.add(SimpleGrantedAuthority(authority.asText()))
        }
        return grantedAuthorities
    }
}